/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;
using EnvDTE;
using System.Globalization;
using System.Runtime.Serialization;

namespace DaveSexton.DocProject
{
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly"), Serializable]
	public class GlobalsSettingsDictionary : BufferedSettingsDictionaryBase<string, string>
	{
		#region Public Properties
		public override bool CanCommit
		{
			get
			{
				return true;
			}
		}

		[CLSCompliant(false)]
		public Globals CommitGlobals
		{
			get
			{
				return commitGlobals;
			}
		}
		#endregion

		#region Private / Protected
		private readonly Globals commitGlobals;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "DaveSexton.DocProject.BufferedSettingsDictionaryBase`2<System.String,System.String>.#ctor")]
		public GlobalsSettingsDictionary(Globals commitGlobals)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		public GlobalsSettingsDictionary(Globals commitGlobals, CultureInfo culture)
			: base(culture)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "DaveSexton.DocProject.BufferedSettingsDictionaryBase`2<System.String,System.String>.#ctor")]
		public GlobalsSettingsDictionary(Globals commitGlobals, int capacity)
			: base(capacity)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "DaveSexton.DocProject.BufferedSettingsDictionaryBase`2<System.String,System.String>.#ctor")]
		public GlobalsSettingsDictionary(Globals commitGlobals, IEqualityComparer<string> comparer)
			: base(comparer)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		public GlobalsSettingsDictionary(Globals commitGlobals, CultureInfo culture, int capacity)
			: base(culture, capacity)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "DaveSexton.DocProject.BufferedSettingsDictionaryBase`2<System.String,System.String>.#ctor")]
		public GlobalsSettingsDictionary(Globals commitGlobals, int capacity, IEqualityComparer<string> comparer)
			: base(capacity, comparer)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		public GlobalsSettingsDictionary(Globals commitGlobals, CultureInfo culture, IEqualityComparer<string> comparer)
			: base(culture, comparer)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class.
		/// </summary>
		[CLSCompliant(false)]
		public GlobalsSettingsDictionary(Globals commitGlobals, CultureInfo culture, int capacity, IEqualityComparer<string> comparer)
			: base(culture, capacity, comparer)
		{
			if (commitGlobals == null)
				throw new ArgumentNullException("commitGlobals");

			this.commitGlobals = commitGlobals;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="GlobalsSettingsDictionary" /> class for deserialization.
		/// </summary>
		protected GlobalsSettingsDictionary(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
		#endregion

		#region Methods
		public override T Read<T>(string name, CultureInfo cultureInfo, T defaultValue)
		{
			try
			{
				return base.Read<T>(name, cultureInfo, defaultValue);
			}
			catch (System.Runtime.InteropServices.COMException)
			{
				return defaultValue;
			}
		}

		public override string GetCommittedValue(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			return (commitGlobals.get_VariableExists(name)) ? ConvertType<object, string>(commitGlobals[name]) : null;
		}

		public override void SetCommittedValue(string name, string value)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			commitGlobals[name] = value;
			commitGlobals.set_VariablePersists(name, true);
		}

		public override bool IsDirty(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			if (!ContainsKey(name))
				return false;
			else
				return !commitGlobals.get_VariableExists(name) || 
					!string.Equals(this[name], ConvertType<object, string>(commitGlobals[name]), StringComparison.CurrentCultureIgnoreCase);
		}

		public override bool IsCommitted(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			return commitGlobals.get_VariableExists(name);
		}

		public override void Delete(string name)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			commitGlobals[name] = null;
		}
		#endregion
	}
}
